// 封装锁 Metux

// 防止头文件被重复包含
#pragma once

#include <iostream>
#include <pthread.h>
#include <cstring>
namespace MutexModel
{

    class Mutex
    {
    public:
        Mutex()
        {
            // 初始化锁
            pthread_mutex_init(&_mutex, nullptr);
        }
        ~Mutex()
        {
            // 销毁锁
            pthread_mutex_destroy(&_mutex);
        }

        // 加锁
        void Lock()
        {
            int n = pthread_mutex_lock(&_mutex);
            if (n == 0)
            {
                //std::cout << " lock success !" << std::endl;
            }
            else
            {
                std::cerr << strerror(n) << std::endl;
            }
        }

        // 解锁
        void Unlock()
        {
            int n = pthread_mutex_unlock(&_mutex);
            if (n == 0)
            {
               // std::cout << " unlock success !" << std::endl;
            }
            else
            {
                std::cerr << strerror(n) << std::endl;
            }
        }

    private:
        pthread_mutex_t _mutex; // 表示一个锁的类型 , 定义一个锁
    };

    // RAII 写法 , 更简洁
    //这个写法的好处就是 : 我们只需要定义一个 LockGuard 对象就可以
    //帮我们完成加锁和解锁过程 
    class LockGuard
    {
    public:
        //构造时把需要的锁传过来
        LockGuard(Mutex& mutex)
        :_mutex(mutex)
        {
            _mutex.Lock();
        }
        ~LockGuard()
        {
            _mutex.Unlock();
        }

    private:
        // 定义一个锁
        Mutex &_mutex;
    };
}